﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lola.Entidades;
using Lola.DTO;
using Lola.DTO.Grilla;

namespace Lola.Servicio
{
    public class Sistema
    {

        private static Sistema _instancia = new Sistema();

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static Sistema getInstancia() {
            return _instancia;
        }

        /// <summary>
        /// Devuelve todos los galpones del sistema
        /// </summary>
        /// <returns></returns>
        public static List<dtoGalpon> obtenerTodosLosGalpones() 
        { 
            return Galpones.obtenerTodosLosGalponesDTO();}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <returns></returns>
        public static List<dtoSectorMicro> getMicrosPorSector(String galpon, String sector) 
        { 
            return Micros.getMicrosDTOenSector(galpon, sector); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<dtoMicroGrilla> getMicrosDisponibles() 
        { 
            return Micros.getMicrosDisponibles(); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <returns></returns>
        public List<dtoMicroGrilla> getMicrosDisponiblesParaSector(String galpon, String sector) 
        {
            return Micros.getMicrosDisponiblesParaSector( galpon,  sector); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <param name="codigoServicio"></param>
        public void RegistrarIngreso(String galpon, String sector, String codigoServicio)
        {
            eInformeSector.RegistrarIngreso(galpon, sector, codigoServicio);
        }

        /// <summary>
        /// Registra el ingreso a un sector
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <param name="codigoServicio"></param>
        public void RegistrarIngresoASector(String galpon, String sector, String codigoServicio) {
            Servicio.Micros.RegistrarIngresoASector(galpon, sector, codigoServicio);
        }

        /// <summary>
        /// Registra la salida de un micro de sector
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <param name="codigoServicio"></param>
        public void RegistrarSalidadeSector(String galpon, String sector, String codigoServicio)
        {
            Servicio.Micros.RegistrarSalidadeSector(galpon, sector, codigoServicio);
        }

        /// <summary>
        /// Obtiene los datos del servicio
        /// </summary>
        /// <param name="codigoServicio"></param>
        /// <returns></returns>
        public dtoServicio ObtenerDatosServicio(String codigoServicio){
           return eServicio.getServicioDTO(codigoServicio); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <param name="codigoServicio"></param>
        /// <returns></returns>
        public Boolean ServicioHabilitadoParaSalir(string galpon, string sector, string codigoServicio)
        {
            return eServicio.ServicioHabilitadoParaSalir(galpon, sector, codigoServicio);
        }

        /// <summary>
        /// Igual a RegistrarSalidadeSector, pero valida si cumplio el circuito
        /// </summary>
        /// <param name="galpon"></param>
        /// <param name="sector"></param>
        /// <param name="codigoServicio"></param>
        /// <returns></returns>
        public Boolean RegistrarSalidadeGalpon(string galpon, string sector, string codigoServicio)
        {
            if (eServicio.ServicioHabilitadoParaSalir(galpon, sector, codigoServicio))
	        {
                Servicio.Micros.RegistrarSalidadeSector(galpon, sector, codigoServicio);
                return true;
	        }
            return false;
        }

        /// <summary>
        /// Obtiene los choferes de un servicio
        /// </summary>
        /// <param name="codigoServicio"></param>
        /// <returns></returns>
        public List<dtoChoferG> obtenerChoferesdeUnServicio(String codigoServicio)
        {
            return eChofer.getChoferesdeUnServicio(codigoServicio);
        }

        public void RegistrarIngresoGalpon(string codigo, List<int> legajos)
        //IMPORTANTE!!! FALTA TODO EL MANEJO DE ERRORES!!!
        {
            //Recibo el codigo del servicio, una lista con los legajos de los choferes,
            //Cuando una unidad ingresa o egresa del galpón se registran los datos de la unidad y de los choferes. El sistema a desarrollar debe,
            //        -	Validar la existencia de la unidad en la tabla de Micros
            //        -	Validar la existencia de los choferes en la tabla de Choferes
            //        -	Validar la existencia del servicio en la tabla Servicio
            //        -	Actualizar el estado del servicio en la tabla Servicio

            eServicio servicio = buscarServicio(codigo);
            if (servicio == null)
            {
                Console.WriteLine("No existe el servicio");
            }
            else
            {
                //Me fijo si el servicio tiene asignado el micro que ingreso a porteria
                if (servicio.existeMicroAsignado())
                {
                    //Me fijo si el servicio tiene asignado los choferes que ingresaron a Porteria
                    if (!servicio.sonChoferesAsignados(codigo, legajos))
                    {
                        Console.WriteLine("Los choferes no estan asignados al servicio");
                    }
                    else
                    {
                        // Esta todo OK -- Actualizo el estado del servicio
                        servicio.actualizarEstadoServicio("En Circuito", servicio.Codigo);
                    }
                }
                else
                {
                    Console.WriteLine("El servicio no tiene Micro asignado");
                }
            }
        }

        private eServicio buscarServicio(string codigo)
        {
            return eServicio.obtenerServicio(codigo);
        }

        public void RegistrarEgresoGalpon(string codigo)
        {
            eServicio servicio = buscarServicio(codigo);
            if (servicio == null)
            {
                Console.WriteLine("No existe el servicio");
            }
            else
            {
                if (servicio.Incidencias != null)
                    servicio.actualizarEstadoServicio("Con Incidencias", servicio.Codigo);
                else
                    servicio.actualizarEstadoServicio("Completo", servicio.Codigo);
            }
        }

        public void RegistarParteNovedades()
        {
            throw new System.NotImplementedException();
        }

        public bool AltaDeIncidencia(string codigo,DateTime fechaInc, string gravedad, string descrip, int prioridad,string galpon,string sector)
        {
            eServicio servicio = buscarServicio(codigo);
            if (servicio == null)
            {
                return false;
            }
            else
            {
               return servicio.altaDeIncidencia(codigo, fechaInc, gravedad, descrip, prioridad,galpon,sector);

            }

        }

        public bool BajaDeIncidencia(string codigo, int numeroInc)
        {
            eServicio servicio = buscarServicio(codigo);
            if (servicio == null)
            {
                return false;
            }
            else
            {
               return  servicio.bajaDeIncidencia(numeroInc);

            }

        }
        public bool ModificarIncidencia(string codigo, int numeroInc,
                                      DateTime fechaInc, string gravedad, string descrip, int prioridad, string estado)
        {

            if (estado.Equals("Abierta"))
            {
                estado = "A";
            }
            else
            {
                if (estado.Equals("Cerrada"))
                {
                    estado = "C";
                }
                else
                {
                    estado = "EC";
                }
            }
                       
            eServicio servicio = buscarServicio(codigo);
            if (servicio == null)
            {
                return false;
            }
            else
            {

                return servicio.modificarIncidencia(numeroInc, fechaInc, gravedad, descrip, prioridad, estado);                 
          
            }
        }

        public List<dtoIncidencia> obtenerIncidenciasPorServicio(string codigo)
        {
            List<dtoIncidencia> listainc = new List<dtoIncidencia>();
            eServicio servicio = buscarServicio(codigo);
            if (servicio == null)
            {
                listainc=null;
            }
            else
            {
                var incidencias = servicio.traerIncidencias();
                for (int i = 0; i < incidencias.Count(); i++)
                {
                    dtoIncidencia incv = incidencias.ElementAt(i).getIncidenciaDTO();
                    if (incv.Estado.Equals("A"))
                    {
                        incv.Estado = "Abierta";
                    }
                    else
                    {
                        if (incv.Estado.Equals("C"))
                        {
                            incv.Estado = "Cerrada";
                        }
                        else
                        {
                            incv.Estado = "En Curso";
                        }
                    }
                    listainc.Add(incv);

                }

            }
            return listainc;
        }

        private List<eServicio> obtenerTodosLosServicios(string galpon)
        {
            eServicio servicio = new eServicio();
            List<eServicio> listaservicios = eServicio.obtenerTodosLosServicios(galpon);
            return listaservicios;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="estado"></param>
        /// <returns></returns>
        public List<dtoIncidencia> ConsultarIncidenciasPorEstado(string estado, string galpon)
        {
            List<dtoIncidencia> listaIncv = new List<dtoIncidencia>();
            List<eServicio> listaservicios = obtenerTodosLosServicios(galpon);
            foreach (eServicio servicio in listaservicios)
            {
                var listinc = servicio.traerIncidencias();
                for (int i = 0; i < listinc.Count(); i++)
                {
                    if (estado.Equals("T"))
                    {
                        dtoIncidencia incv = listinc.ElementAt(i).getIncidenciaDTO();
                        if (incv.Estado.Equals("A"))
                        {
                            incv.Estado = "Abierta";
                        }
                        else
                        {
                            if (incv.Estado.Equals("C"))
                            {
                                incv.Estado = "Cerrada";
                            }
                            else
                            {
                                incv.Estado = "En Curso";
                            }
                        }

                        listaIncv.Add(incv);
                    }

                    else
                    {
                        if (listinc.ElementAt(i).Estado.Equals(estado))
                        {
                            dtoIncidencia incv = listinc.ElementAt(i).getIncidenciaDTO();
                            if (incv.Estado.Equals("A"))
                            {
                                incv.Estado = "Abierta";
                            }
                            else
                            {
                                if (incv.Estado.Equals("C"))
                                {
                                    incv.Estado = "Cerrada";
                                }
                                else
                                {
                                    incv.Estado = "En Curso";
                                }
                            }
                            listaIncv.Add(incv);
                        }
                    }
                }

            }
            return listaIncv;
        }

        /// <summary>
        /// Obtiene los micros en un sector de un galpon
        /// </summary>
        /// <param name="sector"></param>
        /// <param name="galpon"></param>
        /// <returns></returns>
        public List<dtoMicro> ConsultarMicrosenSector(String sector, String galpon)
        {
            List<eMicro> micros = eMicro.obtenerMicrosporSector(sector, galpon);
            List<dtoMicro> res = new List<dtoMicro>();
            foreach (eMicro mi in micros)
            {
                dtoMicro mv = mi.getMicroDTO();
                res.Add(mv);
            }
            return res;
        }
        
        public List<dtoMicro> ConsultarMicros()
        {
            return Micros.getMicrosDTO();
        }

        /// <summary>
        /// Registra el control de alcoholemia de un conductor. 
        /// Devuelve true si lo pudo hacer
        /// Devuelve false si no pudo, por ejemplo por ya existir otro control de alcoholemia
        /// </summary>
        /// <param name="_codigoServicio"></param>
        /// <param name="p"></param>
        /// <param name="p_2"></param>
        public Boolean RegistrarControlAlcoholemia(string codigoServicio, int legajo, int resultado)
        {
            return eControlAlcoholemia.RegistrarControlAlcoholemia(codigoServicio, legajo, resultado);
        }

        public List<dtoGrillaTrafico> obtenerMicrosenGalponTrafico(string galpon)
        {
            return Micros.obtenerMicrosenGalponTrafico(galpon);
        }

        public List<dtoControlAlcoholemia> getControlesAlcoholemia()
        {
            return eControlAlcoholemia.getControlesAlcoholemia();
        }

    }
}
